/*
 * Copyright (C) 2016 Baidu, Inc. All Rights Reserved.
 */
package com.baidu.mapsdkexample.routeplan;

import java.util.ArrayList;
import java.util.List;

import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapPoi;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.Marker;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.model.LatLngBounds;
import com.baidu.mapapi.search.core.RouteLine;
import com.baidu.mapapi.search.core.SearchResult;
import com.baidu.mapapi.search.route.BikingRouteResult;
import com.baidu.mapapi.search.route.DrivingRouteResult;
import com.baidu.mapapi.search.route.IndoorRouteResult;
import com.baidu.mapapi.search.route.MassTransitRouteResult;
import com.baidu.mapapi.search.route.OnGetRoutePlanResultListener;
import com.baidu.mapapi.search.route.PlanNode;
import com.baidu.mapapi.search.route.RoutePlanSearch;
import com.baidu.mapapi.search.route.TransitRouteLine;
import com.baidu.mapapi.search.route.TransitRoutePlanOption;
import com.baidu.mapapi.search.route.TransitRouteResult;
import com.baidu.mapapi.search.route.WalkingRouteResult;
import com.baidu.mapsdkexample.R;
import com.baidu.mapsdkexample.util.Utils;
import com.baidu.mapsdkexample.util.overlayutil.TransitRouteOverlay;

import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;

/**
 * 此demo用来展示如何进行公交路线搜索并在地图使用RouteOverlay、TransitOverlay绘制
 * 同时展示如何进行节点浏览并弹出泡泡
 */
public class TransitRoutePlanActivity extends AppCompatActivity
        implements BaiduMap.OnMapClickListener,
        OnGetRoutePlanResultListener, View.OnClickListener {

    private RouteLine mRouteLine = null;

    // 地图相关，使用继承MapView的MyRouteMapView目的是重写touch事件实现泡泡处理
    // 如果不处理touch事件，则无需继承，直接使用MapView即可
    private MapView mMapView = null;    // 地图View
    private BaiduMap mBaidumap = null;
    // 搜索相关
    private RoutePlanSearch mSearch = null;    // 搜索模块，也可去掉地图模块独立使用

    private LocationClient mLocClientOne = null;//定位用
    private Marker mOneLocMarker = null;
    private BitmapDescriptor mBitmapBlue = BitmapDescriptorFactory.fromResource(R.drawable.markerblue);

    private ArrayList<String> Nodes=new ArrayList<>();
    private ListView nodelistview;
    private Button addNode;
    private AutoCompleteTextView addtext;

    private View mBottomOverviewCard = null;
    private TextView mETAText = null;

    private List<? extends RouteLine> mRouteLines;
    private ListView mRouteListView = null;
    private RouteLineListAdapter mRouteLineListAdapter = null;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_transit_route);

        Log.d("which","TransitRoutePlanActivity");

        // 初始化地图
        mMapView = (MapView) findViewById(R.id.map);
        mBaidumap = mMapView.getMap();

        // 地图点击事件处理
        mBaidumap.setOnMapClickListener(this);
        // 初始化搜索模块，注册事件监听
        mSearch = RoutePlanSearch.newInstance();
        mSearch.setOnGetRoutePlanResultListener(this);

        initMapView();
        initView();
        startOneLocaton();
        Nodes.add("图书馆地铁站");
        Nodes.add("十里庙地铁站");
        Nodes.add("汽车客运西站");
        Nodes.add("讯飞大厦");

        nodelistview=findViewById(R.id.nodelistview);
        addtext=findViewById(R.id.addtext);
        addNode=findViewById(R.id.addNode);
        addNode.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Nodes.add(addtext.getText().toString().trim());
                ArrayAdapter<String> nodeAdapter=new NodeAdapter(TransitRoutePlanActivity.this,R.layout.layout_node_item,Nodes);//刷新listview，可改进？？？？？？
                nodelistview.setAdapter(nodeAdapter);
            }
        });
        ArrayAdapter<String> nodeAdapter=new NodeAdapter(this,R.layout.layout_node_item,Nodes);//第一次刷新listview  即初始化
        nodelistview.setAdapter(nodeAdapter);
    }

    private void initMapView() {
        Log.d("temp","TransitRoutePlanActivity--initMapView");
        mMapView.showZoomControls(false);
        mMapView.showScaleControl(false);
        mBaidumap.setViewPadding(20, 0, 0, 20);
    }

    private void startOneLocaton() {
        mLocClientOne = new LocationClient(this);
        mLocClientOne.registerLocationListener(oneLocationListener);
        LocationClientOption locationClientOption = new LocationClientOption();
        // 可选，设置定位模式，默认高精度 LocationMode.Hight_Accuracy：高精度；
        locationClientOption.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
        // 可选，设置返回经纬度坐标类型，默认GCJ02
        locationClientOption.setCoorType("bd09ll");
        // 如果设置为0，则代表单次定位，即仅定位一次，默认为0
        // 如果设置非0，需设置1000ms以上才有效
        locationClientOption.setScanSpan(0);
        // 设置是否进行单次定位，单次定位时调用start之后会默认返回一次定位结果
        locationClientOption.setOnceLocation(true);
        //可选，设置是否使用gps，默认false
        locationClientOption.setOpenGps(true);
        // 可选，是否需要地址信息，默认为不需要，即参数为false
        // 如果开发者需要获得当前点的地址信息，此处必须为true
        locationClientOption.setIsNeedAddress(true);
        // 设置定位参数
        mLocClientOne.setLocOption(locationClientOption);
        // 开启定位
        mLocClientOne.start();
    }


    private void initRouteOverViewData() {
        Log.d("temp","TransitRoutePlanActivity--initRouteOverViewData");
        //建立 mRouteLineListAdapter 和 mRouteLines 之间的连接
        mRouteLineListAdapter =
                new RouteLineListAdapter(TransitRoutePlanActivity.this.getApplicationContext(),
                        mRouteLines,
                        RouteLineListAdapter.Type.TRANSIT_ROUTE);
        mRouteListView.setAdapter(mRouteLineListAdapter);
    }


    //先找到各种控件
    private void initView() {
        Log.d("temp","TransitRoutePlanActivity--initView");
        // 路线概览卡片
        mBottomOverviewCard = findViewById(R.id.rooter_search);
        mETAText = (TextView) findViewById(R.id.eta_text);
        Button detailButton = (Button) findViewById(R.id.route_detail_button);
        detailButton.setOnClickListener(this);


        // 路线列表
        mRouteListView = (ListView) findViewById(R.id.route_result_listview);
        mRouteListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Log.d("temp","initView position = "+position);
                if (mRouteLines == null) {
                    return;
                }
                mRouteListView.setVisibility(View.GONE);
                mBottomOverviewCard.setVisibility(View.VISIBLE);

                mRouteLine = mRouteLines.get(position);

                // 路线概览
                updateRouteOverViewCard((TransitRouteLine) mRouteLine);

                // 路线绘制
                TransitRouteOverlay overlay = new MyTransitRouteOverlay(mBaidumap);
                mBaidumap.setOnMarkerClickListener(overlay);
                overlay.setData((TransitRouteLine) mRouteLine);
                overlay.addToMap();
                overlay.zoomToSpanPaddingBounds(100, 500, 100, 500);
            }
        });
        nodelistview=findViewById(R.id.nodelistview);
        nodelistview.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                Nodes.remove(position);
                ArrayAdapter<String> nodeAdapter=new NodeAdapter(TransitRoutePlanActivity.this,R.layout.layout_node_item,Nodes);//刷新listview
                nodelistview.setAdapter(nodeAdapter);
                Toast.makeText(TransitRoutePlanActivity.this, "删除成功", Toast.LENGTH_SHORT).show();
                return false;
            }
        });
    }


    private void updateRouteOverViewCard(RouteLine routeLine) {
        Log.d("temp","TransitRoutePlanActivity--updateRouteOverViewCard");
        String totalTime = "";
        String totalDistance = "";
        int time = routeLine.getDuration();
        if (time / 3600 == 0) {
            totalTime = time / 60 + "分钟";
        } else {
            totalTime = time / 3600 + "小时" + (time % 3600) / 60 + "分钟";
        }

        int distance = routeLine.getDistance();
        if (distance / 1000 == 0) {
            totalDistance = distance + "米";
        } else {
            totalDistance = String.format("%.1f", distance / 1000f) + "公里";
        }

        mETAText.setText(totalTime + " " + totalDistance);
    }

    /**
     * 发起路线规划搜索示例
     */
    public void searchButtonProcess(View v) {
        Log.d("temp","TransitRoutePlanActivity--searchButtonProcess");
        Utils.hideKeyBoard(TransitRoutePlanActivity.this);
        if (mRouteLines != null) {
            // 重置路线数据
            mRouteLines.clear();
            mRouteLines = null;
        }

        if (mBottomOverviewCard.getVisibility() == View.VISIBLE) {
            mBottomOverviewCard.setVisibility(View.GONE);
        }

        // 清除之前的覆盖物
        mBaidumap.clear();
        // 设置起终点信息 起点参数
        ArrayList<PlanNode> planNodes=new ArrayList<PlanNode>();
        ArrayList<TransitRoutePlanOption> transitRoutePlanOptions=new ArrayList<TransitRoutePlanOption>();

        for (int i=0;i<Nodes.size();i++){
            planNodes.add(PlanNode.withCityNameAndPlaceName("合肥", Nodes.get(i)));
        }

        for (int i=0;i<Nodes.size()-1;i++){
            transitRoutePlanOptions.add(new TransitRoutePlanOption().from(planNodes.get(i)).to(planNodes.get(i+1)).city("合肥"));
            //
            //
            //发起换乘路线规划
            mSearch.transitSearch(transitRoutePlanOptions.get(i));//查找-----------------------------------------------------------------
        }
    }

    /*****
     *
     * 单次定位回调监听
     *
     */
    private BDAbstractLocationListener oneLocationListener = new BDAbstractLocationListener() {

        /**
         * 定位请求回调函数
         * @param location 定位结果
         */
        @Override
        public void onReceiveLocation(BDLocation location) {
            if (null == location || null == mBaidumap) {
                return;
            }
            LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());

            addOneLocMarker(latLng);
            LatLngBounds.Builder builder = new LatLngBounds.Builder();
            builder.include(latLng);
            int padding = 0;
            int paddingBottom = 600;
            MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.newLatLngBounds(builder.build(), padding,
                    padding, padding, paddingBottom);
            StringBuffer sb = new StringBuffer(256);
            // 更新地图状态
            mBaidumap.animateMapStatus(mapStatusUpdate);
            if (location.getLocType() == BDLocation.TypeGpsLocation) {// GPS定位结果
                sb.append("gps定位成功");
            } else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {// 网络定位结果
                sb.append("网络定位成功");
            } else if (location.getLocType() == BDLocation.TypeOffLineLocation) {// 离线定位结果
                sb.append("离线定位成功");
            } else if (location.getLocType() == BDLocation.TypeServerError) {
                sb.append("服务端网络定位失败");
            } else if (location.getLocType() == BDLocation.TypeNetWorkException) {
                sb.append("网络不同导致定位失败，请检查网络是否通畅");
            } else if (location.getLocType() == BDLocation.TypeCriteriaException) {
                sb.append("无法获取有效定位依据导致定位失败，一般是由于手机的原因，处于飞行模式下一般会造成这种结果，可以试着重启手机");
            }
            String locationStr = Utils.getLocationStr(location, mLocClientOne);
            if (!TextUtils.isEmpty(locationStr)) {
                sb.append(locationStr);
            }
            Toast.makeText(TransitRoutePlanActivity.this, sb, Toast.LENGTH_SHORT).show();
            mLocClientOne.stop();
        }
    };

    /**
     * 添加marker
     *
     * @param latLng
     */
    private void addOneLocMarker(LatLng latLng) {
        if (null != mOneLocMarker) {
            mOneLocMarker.remove();
        }
        MarkerOptions markerOptions = new MarkerOptions();
        markerOptions.position(latLng);
        markerOptions.icon(mBitmapBlue);
        mOneLocMarker = (Marker) mBaidumap.addOverlay(markerOptions);
    }

    @Override
    public void onGetWalkingRouteResult(WalkingRouteResult result) {
        Log.d("temp","TransitRoutePlanActivity--onGetWalkingRouteResult(empty)");
    }

    //search完成后使用结果监听器解析获得的result
    @Override
    public void onGetTransitRouteResult(TransitRouteResult result) {
        Log.d("temp","结果监听器  "+result.error);
        if (result != null && result.error == SearchResult.ERRORNO.AMBIGUOUS_ROURE_ADDR) {
            // 起终点或途经点地址有岐义，通过以下接口获取建议查询信息
            // result.getSuggestAddrInfo()
            Toast.makeText(TransitRoutePlanActivity.this,
                    "起终点或途经点地址有岐义，通过result.getSuggestAddrInfo()接口获取建议查询信息",
                    Toast.LENGTH_SHORT).show();
            return;
        }

        if (result == null || result.error == SearchResult.ERRORNO.RESULT_NOT_FOUND) {
            Toast.makeText(TransitRoutePlanActivity.this, "抱歉，未找到结果", Toast.LENGTH_SHORT).show();
            return;
        }

        if (result.error == SearchResult.ERRORNO.NO_ERROR) {
            mRouteListView.setVisibility(View.VISIBLE);//将列表设为可见
            if (mRouteLines != null) {
                mRouteLines.clear();
            }
            mRouteLines = result.getRouteLines();//返回一个列表
            initRouteOverViewData();
            mRouteLineListAdapter.notifyDataSetChanged();

            //
            //
            //
            //自己添加  mRouteLineListAdapter.getCount()
            //暂时取第一个搜索结果
            for (int position=0;position<1;position++) {
                Log.d("temp", "initView position = " + position);
                if (mRouteLines == null) {
                    return;
                }
                mRouteListView.setVisibility(View.GONE);
                mBottomOverviewCard.setVisibility(View.VISIBLE);

                mRouteLine = mRouteLines.get(position);

                // 路线概览
                updateRouteOverViewCard((TransitRouteLine) mRouteLine);

                // 路线绘制
                TransitRouteOverlay overlay = new MyTransitRouteOverlay(mBaidumap);
                mBaidumap.setOnMarkerClickListener(overlay);
                overlay.setData((TransitRouteLine) mRouteLine);
                overlay.addToMap();
                overlay.zoomToSpanPaddingBounds(100, 500, 100, 500);
            }
        }
    }

    @Override
    public void onGetMassTransitRouteResult(MassTransitRouteResult result) {

    }

    @Override
    public void onGetDrivingRouteResult(DrivingRouteResult result) {

    }

    @Override
    public void onGetIndoorRouteResult(IndoorRouteResult indoorRouteResult) {

    }

    @Override
    public void onGetBikingRouteResult(BikingRouteResult result) {

    }

    private static class MyTransitRouteOverlay extends TransitRouteOverlay {


        private MyTransitRouteOverlay(BaiduMap baiduMap) {
            super(baiduMap);
            Log.d("temp","TransitRoutePlanActivity--MyTransitRouteOverlay--构造函数");
        }

        @Override
        public BitmapDescriptor getStartMarker() {
            Log.d("temp","TransitRoutePlanActivity--MyTransitRouteOverlay--getStartMarker 获取起点图标");
            return BitmapDescriptorFactory.fromResource(R.drawable.icon_start);
        }

        @Override
        public BitmapDescriptor getTerminalMarker() {
            Log.d("temp","TransitRoutePlanActivity--MyTransitRouteOverlay--getTerminalMarker 获取终点图标");
            return BitmapDescriptorFactory.fromResource(R.drawable.icon_end);
        }
    }

    @Override
    public void onMapClick(LatLng point) {
        Log.d("temp","TransitRoutePlanActivity--onMapClick");
        mBaidumap.hideInfoWindow();
        Utils.hideKeyBoard(this);
    }

    @Override
    public void onMapPoiClick(MapPoi poi) {
        Log.d("temp","TransitRoutePlanActivity--onMapPoiClick");
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.route_detail_button:
                Intent intent = new Intent(TransitRoutePlanActivity.this.getApplicationContext(),
                        RouteDetailActivity.class);
                intent.putExtra("route_plan_result", mRouteLine);
                intent.putExtra("route_plan_type", 1);
                startActivity(intent);
                break;

            default:
                break;
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        mMapView.onPause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        mMapView.onResume();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 释放检索对象
        if (mSearch != null) {
            mSearch.destroy();
        }
        mBaidumap.clear();
        mMapView.onDestroy();
    }
}
